#pragma once
#include <iostream>
#include <cstring>
#include <sys/types.h>
#include <sys/socket.h>
// #include "Log.hpp"
#include <jsoncpp/json/json.h>

using namespace std;

// #define MYSELF 1 // 自定义的协议
#define SPACE " "
#define SPACE_LEN strlen(SPACE)
#define SEP "\r\n"
#define SEP_LEN strlen(SEP)

namespace ns_protocol
{
    class Request // 计算请求
    {
    public:
        string Serialize() // 序列化
        {
#ifdef MYSELF
            //"_x _op _y"
            return to_string(_x) + SPACE + _op + SPACE + to_string(_y);
#else
            Json::Value root;
            root["x"] = _x;
            root["y"] = _y;
            root["op"] = _op;
            Json::FastWriter writer;
            return writer.write(root);
#endif
        }

        bool DeSerialized(const string &str) // 反序列化
        {
#ifdef MYSELF
            size_t left_space = str.find(SPACE);
            if (left_space == string::npos)
                return false;
            size_t right_space = str.rfind(SPACE);
            if (right_space == string::npos || left_space == right_space)
                return false;

            _x = atoi(str.substr(0, left_space).c_str());
            _y = atoi(str.substr(right_space + SPACE_LEN).c_str());
            _op = str[left_space + SPACE_LEN];
            return true;
#else
            Json::Value root;
            Json::Reader reader;
            reader.parse(str, root);
            _x = root["x"].asInt();
            _y = root["y"].asInt();
            _op = root["op"].asInt();
            return true;
#endif
        }

    public:
        Request() {}
        Request(int x, int y, char op)
            : _x(x), _y(y), _op(op)
        {
        }
        ~Request() {}
        int _x;
        int _y;
        char _op;
    };

    class Response // 计算响应
    {
    public:
        string Serialize() // 序列化
        {
#ifdef MYSELF
            //"_result _code"
            return to_string(_result) + SPACE + to_string(_code);
#else
            Json::Value root;
            root["x"] = _x;
            root["y"] = _y;
            root["op"] = _op;
            root["result"] = _result;
            root["code"] = _code;
            Json::FastWriter writer;
            return writer.write(root);
#endif
        }

        bool DeSerialized(const string &str) // 反序列化
        {
#ifdef MYSELF
            ssize_t spacei = str.find(SPACE);
            if (spacei == string::npos || spacei + SPACE_LEN > str.size())
                return false;
            _result = atoi(str.substr(0, spacei).c_str());
            _code = atoi(str.substr(spacei + SPACE_LEN).c_str());
            return true;
#else
            Json::Value root;
            Json::Reader reader;
            reader.parse(str, root);
            _x = root["x"].asInt();
            _y = root["y"].asInt();
            _op = root["op"].asInt();
            _result = root["result"].asInt();
            _code = root["code"].asInt();
            return true;
#endif
        }

    public:
        Response(int x, int y, char op) : _x(x), _y(y), _op(op)
        {
            _code = 0;
            _result = 0;
        }
        Response()
        {
            _code = 0;
            _result = 0;
        }
        ~Response() {}
        int _x;
        int _y;
        int _op;
        int _result;
        int _code; // 错误码：除0? 运算符未定义? ......
    };

    bool Recv(int sock, string *out) // 从sock读取数据
    {
        char buffer[1024];
        ssize_t s = recv(sock, buffer, sizeof(buffer) - 1, 0);
        if (s > 0) // 读到数据
        {
            buffer[s] = 0;
            *out += buffer;
            return true;
        }
        else if (s == 0) // 客户端退出(断开连接)
        {
            // logMessage(NORMAL, "客户端关闭,sock:%d", sock);
            return false;
        }
        else // 读数据出错
        {
            // logMessage(ERROR, "读数据出错,sock:%d", sock);
            return false;
        }
    }

    void Send(int sock, const string &respString) // 送回计算好的resp的序列化字符串
    {
        if (send(sock, respString.c_str(), respString.size(), 0) < 0)
        {
            // logMessage(NORMAL, "对端关闭");
        }
    }
    // length\r\n请求报文\r\n
    string Decode(string &buffer) // 提取出一个完整的请求报文
    {
        size_t pos = buffer.find(SEP); // 找到分隔符位置
        if (pos == string::npos)
            return "";                                              // 说明此时报文肯定不完整
        int len = atoi(buffer.substr(0, pos).c_str());              // 提取出length
        int content_size = buffer.size() - pos - SEP_LEN - SEP_LEN; // buffer.size() -length所占字节数 -2个分隔符所占字节数
        if (content_size >= len)                                    // 至少有一个完整的请求报文,开始提取
        {
            buffer.erase(0, pos + SEP_LEN);     // 先删去length\r\n
            string str = buffer.substr(0, len); // 拿到报文
            buffer.erase(0, len + SEP_LEN);     // 再删去 请求报文\r\n
            // 剩下的就又是新报文了
            return str;
        }
        else // 还不完整,例如：length\r\n12345 +
        {
            return "";
        }
    }

    string Encode(string &str)
    {
        return to_string(str.size()) + SEP + str + SEP;
    }

    // buffer：传入一个连接的接收缓冲区，可能1个，n个完整报文，或没有完整报文
    // out：将完整的报文切分到数组内，不完整的则继续留在buffer内
    void SpliteRequest(string &buffer, vector<string> *out)
    {
        while (true)
        {
            string reqstring = Decode(buffer);
            if (reqstring.empty())
                break;
            else
                out->push_back(reqstring);
        }
    }
};